企业级扫描平台关于JS扫描落地与实践

企业级扫描平台EOS关于JS扫描落地与实践

程序是写给人读的,只是偶尔让计算机执行一下。—— Donald Knuth

引言

随着前端应用的大型化和复杂化,越来越多的前端工程师和团队开始重视 JavaScript 代码规范。得益于前端开源社区的繁盛,当下已经有几种较为成熟的 JavaScript 代码规范检查工具,包括 JSLint、JSHint、ESLint、FECS 等等。EOS-JS,它是一款插件化的JavaScript 代码静态检查工具,具备全套的热修复、增量更新方案,集各类代码规范检查工具优势于一体,其核心是通过对代码解析得到的 AST(Abstract Syntax Tree,抽象语法树)进行模式匹配,定位不符合约定规范的代码、给出修改意见并支持一键修复,在降低维护成本、提升执行效率的同时,也保障了代码规范的统一。

为实现规范编码、提高编码质量,目前较为通用的是直接使用开源生态中提供的一些标准方案,可以用较低成本来实现 JavaScript 代码规范的落地。如果再搭配一些辅助工具(例如 husky 和 lint-staged),整个流程会更加顺畅。但是对于大型企业开发团队而言,数十人甚至上千人面对数万个工程,规模化地应用统一的 JavaScript 代码规范,并且有效落地执行,问题就会变得较为复杂。

痛点分析

设计初期,我们收集了大量前端开发人员的编码痛点,可以归纳为以下几点:

人员角度

  • 公司部门团队较多,从上往下宣传,执行难度较大
  • 团队(人员)风格差异大的,不是每个团队都自愿去梳理适用的规则集
  • 没有数据统计和有效的监管方案,人员执行状况及编码优化成效没办法衡量

技术角度

  • 技术选型分散, React、Vue、JavaScript、TypeScript 等
  • 开发工具可选性多,Vscode、WebStorm等
  • 工程量大,每个工程都按照开源方案进行配置,复杂度提升,管理混乱

解决方案

针对上文中提出的问题,我们设计了一套完整的技术解决档案,基于EOS-JS提供了插件端和平台端两种扫描方法,用户可结合实际情况自由选择。

EOS-JS是一个扫描引擎,通过基础检测能力和模式约束,推动代码检测流程的运转。原始代码经过解析器的解析,在管道中逐一经过所有规则的检查,最终检测出所有不符合规范的代码,并输出为报告。

整体设计方案分为以下几点:

  • 定位问题与自动修复:该模块是整体方案的基石,通过解析代码得到AST,进行模式匹配,定位不符合约定规范的代码,并针对通用规范问题编码提供自动修复能力。
  • 多场景通用规范(核心):通过分层分类的结构设计,在保证基础规则一致性的同时,实现了对不同场景、技术选型的支撑。
  • 自动化接入升级:通过JD插件中心实现两端(Plugin/Server)“一键”接入,自动升级,极大降低了工程接入和维护的成本。
  • 多端代码检测:该模块是方案落地执行的保障,将代码检查与本地实时编码及CI持续集成工作流程相结合。在保证代码集成质量的同时,也通过定制集成检查/修复工具降低了开发者的应用执行成本。
  • 数据统计可视化:通过对工具运行和代码集成检查过程进行埋点、检查结果收集和分析,了解方案的应用状态和效果。

整体方案设计图如下所示:

具体实现

整体方案已确认,但具体到各个模块的实现,仍然需要进一步深入思考,以设计出更加合理的实现方案。本章将对方案的几大核心模块进行详细介绍。

定位问题、自动修复

代码解析,获取问题数据源是开发扫描引擎,统计编码问题的前提。

AST编译简介

AST:简单理解,就是把我们写的代码按照一定的规则转换成一种树形结构。在javascript世界中,可以认为抽象语法树(AST)是最底层, 再往下,就是关于转换和编译的“黑魔法”领域了。我们常见的前端开发插件javascript转译、代码压缩、css预处理器、pretiier等都建立在了AST这个巨人的肩膀上。EOS-JS引擎集百家之所长,基于AST抽象 JS 源码的共性,分析源码,进行模式匹配,检查问题。

编译流程主要分为以下四步:

  • 词法分析scanner
  • parser生成AST树
  • traverse对AST树遍历,进行增删改查
  • generator将更新后的AST转化成代码

可以很清楚的看出,实现代码扫描,可以在parser生成AST树后,进行模式匹配。实例演示如下:

1.代码解析

insert函数解析后,得到如下所示结构体:

2.解析后可以做什么

提出修改建议、一键修复。

实际编码过程中,我们充分利用AST优势针对常见编码规范问题例如:注释、代码替换等提供了一键修复能力,提高了开发者编码效率。
继续以insert函数为例,基于我们前面得到的insert函数体的语法树分析,实现代码替换功能:

多场景通用规范

这一模块是整体方案的核心,采用分层分类的结构设计,提供多场景、多技术方案的通用配置方案,解决了用户最大的痛点,并使方案具备易维护、易扩展的特性。

详细配置方案如下:

EOS-JS扫描引擎借助插件化设计原理,与解析器解绑,我们可以使用不同的解析器进行原始代码解析,例如使用不同的解析器处理 ES 语法与TypeScript 语言。最终实现所有的规则可独立控制,并且具备自定义拓展能力。

动态配置化方案

EOS-JS提供了全面、灵活的配置能力,可以对解析器、规则、环境、全局变量等进行配置;还可以配置层叠、实现配置共享。具体的使用中,各团队可以根据部门需求灵活的选择各层级、各类型的搭配,在代码检测平台获得和项目匹配的规则集,如仍不满足需求,也可以通过自定义规则集,得到自己预期的统一规范工具。

Base层:通过公司内部前端开发团队制定统一的基础语法和格式规范,提供通用的代码风格和语法规则配置。

框架支撑层:提供对通用的一些技术场景、框架的支持,包括 Node.js、React、Vue、等;这一层借助多个团队对各种框架的规则使用建议,整合出适配各种框架的规则集。

TS层:这一层提供对TypeScript 的支持。
扩展(自定义)层:针对团队的特殊规则诉求,提供定制化支持,目前已存在的JDSpecification便是为公司内部定制的前端代码扫描规范。

这种分层分类、配置解耦的设计结构,存在以下优势:

  • 对Base层级的修改,影响全局。
  • 对非基础层某一部分的调整不会产生关联性的影响。
  • 如需扩展对某一类型的支持,团队通过自定义,配置完成后,只需关注这一类型的特殊规则配置。

该方案已在公司内部得到广泛使用,例如:Plus团队在平台配置自定义React规范,扫描该团队的React项目时规则即时生效,这种通过分层、分类的结构设计,节省了用户使用成本的同时,减少了规则维护成本,规则示例代码如下:

自动化接入升级

前端开发人员在开源方案的使用中经常遇到规则无效、兼容性、解析异常等问题,反复排查和定位问题会浪费大量的精力。因此在设计接入及升级流程时,我们充分考虑了规则集和工程方案的兼容性、用户使用场景、接入成本,操作体验等,采用了Plugin和Server可独立运行,亦可协同工作的设计模式。一键接入,自动升级,为用户带来良好的使用体验。
工作流程如下图所示:

我们开发了JDPluginCenter插件,支持用户多场景需求,无论什么开发场景和框架选型,繁琐的接入流程都只需要用户安装JDPluginCenter或是一条命令集成到项目脚手架,便可实现在插件和平台两端的接入流程。

多端代码检测

为避免因一些主观因素或疏漏造成的编码规范执行不到位,我们将代码规范静态检查与开发工作流集成,保证代码规范的有效落实。

本地开发实时检查:本地编码过程中,EOS-VSCode插件有两种检查方式可供选择。实时检查编码问题给出修改建议,也可以针对单个文件、单个文件夹或者整个项目手动触发,开启检查流程,并将结果展示到前台。其优点在于实时性,可在编码过程中发现并解决编码规范及质量问题。

代码提交检查:在代码 Commit 时,通过 gitHook 触发代码检查。其优点在于能实时响应开发者的动作,给出反馈,快速定位和修复问题
代码集成检查:在代码集成(借助 CI 系统的集成流程功能)时,通过代码检测平台对代码进行检查,检测不通过则阻断集成。其优点在于能够强制执行,可在线追踪检测报告。

Server端检查:代码库源码或构建产物在服务端扫描。支持自动化定时扫描和用户主动触发扫描两种方式,其优点在于可以按照不同维度进行数据统计,对上可以有效监管,对下可以高效落实。

数据统计可视化

数据统计

核心是信息采集和分析。在本方案中:

  • 执行状况监测:插件启动、关闭、用户信息、仓库地址等信息上报后,可精确分析使用率、扫描成功率、用户活跃度等。
  • 扫描结果分析:插件端、CI持续集成节点、Server端扫描都会结果上报扫描结果,包括检查是否通过、blocker和warning信息的数量、问题代码段、问题代码行号等。

分析及数据可视化

该模块包含插件端可视化和平台可视化两部分:

  • 插件端:实时检测,编码建议即时提醒;手动扫描,结果分析统计后展示到编辑器view,供开发人员直接定位问题代码行。

  • 平台端:个人、团队、工程等各维度进行数据汇总,通过图形、报表多种类型进行数据展示及邮件通知。
    某团队编码问题变化趋势:

以上是共享技术部-移动技术研发组在检查前端编码规范及编码质量过程中的一些实践,欢迎交流共建。

联系人:

技术与数据中心-共享技术部

单霞(erp:shanxia)